package com.example.wenhua.service.impl;

import com.example.wenhua.dto.DeepSeekRequest;
import com.example.wenhua.dto.DeepSeekResponse;
import com.example.wenhua.service.AiQueryService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

/**
 * AI查询服务实现类
 */
@Slf4j
@Service
public class AiQueryServiceImpl implements AiQueryService {
    
    @Value("${deepseek.api.url}")
    private String deepseekApiUrl;
    
    @Value("${deepseek.api.key}")
    private String apiKey;
    
    @Value("${deepseek.api.model}")
    private String model;
    
    @Value("${deepseek.api.timeout}")
    private int timeout;
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public String parseNaturalLanguageQuery(String userQuery) {
        try {
            // 构建系统提示词
            String systemPrompt = buildDatabaseSchemaPrompt() + 
                "\n\n请根据用户的自然语言查询，生成对应的SQL语句。" +
                "\n要求：" +
                "\n1. 只生成SELECT查询语句，不允许INSERT、UPDATE、DELETE等操作" +
                "\n2. 确保SQL语法正确" +
                "\n3. 使用合适的WHERE条件和JOIN操作" +
                "\n4. 返回格式：只返回SQL语句，不要其他解释文字" +
                "\n5. 如果查询不明确，返回最合理的解释";
            
            // 构建请求消息
            List<DeepSeekRequest.Message> messages = Arrays.asList(
                new DeepSeekRequest.Message("system", systemPrompt),
                new DeepSeekRequest.Message("user", userQuery)
            );
            
            // 创建请求对象
            DeepSeekRequest request = new DeepSeekRequest();
            request.setModel(model);
            request.setMessages(messages);
            request.setTemperature(0.1); // 降低随机性，提高准确性
            request.setMaxTokens(1000);
            
            // 调用API
            DeepSeekResponse response = callDeepSeekApi(request);
            
            if (response != null && response.getChoices() != null && !response.getChoices().isEmpty()) {
                String aiResponse = response.getChoices().get(0).getMessage().getContent().trim();
                log.info("AI完整响应内容: {}", aiResponse);
                return aiResponse;
            }
            
            log.warn("AI响应为空或无有效选择");
            return "无法解析查询，请重新描述您的需求";
            
        } catch (Exception e) {
            log.error("解析自然语言查询失败: {}", e.getMessage(), e);
            return "查询解析失败: " + e.getMessage();
        }
    }
    
    @Override
    public DeepSeekResponse callDeepSeekApi(DeepSeekRequest request) {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(deepseekApiUrl);
        
        try {
            // 设置请求头
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("Authorization", "Bearer " + apiKey);
            
            // 设置请求体
            String requestBody = objectMapper.writeValueAsString(request);
            StringEntity entity = new StringEntity(requestBody, "UTF-8");
            httpPost.setEntity(entity);
            
            log.info("调用DeepSeek API，请求: {}", requestBody);
            
            // 执行请求
            HttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            String responseBody = EntityUtils.toString(response.getEntity());
            
            log.info("DeepSeek API响应状态: {}, 响应体: {}", statusCode, responseBody);
            
            if (statusCode == 200) {
                return objectMapper.readValue(responseBody, DeepSeekResponse.class);
            } else {
                log.error("DeepSeek API调用失败，状态码: {}, 响应: {}", statusCode, responseBody);
                return null;
            }
            
        } catch (Exception e) {
            log.error("调用DeepSeek API异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    @Override
    public String buildDatabaseSchemaPrompt() {
        return "数据库结构信息：\n" +
            "\n数据库名：wenhua" +
            "\n\n表结构：" +
            "\n1. 学生表 s:" +
            "\n   - sno (CHAR(10), 主键): 学号" +
            "\n   - sname (VARCHAR(50)): 姓名" +
            "\n   - sex (ENUM('男','女')): 性别" +
            "\n   - age (INT): 年龄" +
            "\n   - dept (VARCHAR(50)): 系名/班级号" +
            "\n\n2. 课程表 c:" +
            "\n   - cno (CHAR(10), 主键): 课程号" +
            "\n   - cname (VARCHAR(100)): 课程名" +
            "\n   - teacher (VARCHAR(50)): 教师名" +
            "\n   - credit (INT): 学分" +
            "\n\n3. 选课表 sc:" +
            "\n   - sno (CHAR(10), 外键): 学号" +
            "\n   - cno (CHAR(10), 外键): 课程号" +
            "\n   - grade (DECIMAL(5,2)): 成绩" +
            "\n   - 主键: (sno, cno)" +
            "\n\n4. 用户表 user:" +
            "\n   - hm (VARCHAR(50), 主键): 用户名" +
            "\n   - pwd (VARCHAR(255)): 密码" +
            "\n   - role (TINYINT): 权限(0=管理员,1=教师,2=学生)" +
            "\n\n表关系：" +
            "\n- s.sno = sc.sno (学生选课关系)" +
            "\n- c.cno = sc.cno (课程选课关系)" +
            "\n\n常见查询示例：" +
            "\n- 查询所有学生: SELECT * FROM s" +
            "\n- 查询某班级学生: SELECT * FROM s WHERE dept = '计算机一班'" +
            "\n- 查询不及格学生: SELECT s.sname, c.cname, sc.grade FROM s JOIN sc ON s.sno = sc.sno JOIN c ON sc.cno = c.cno WHERE sc.grade < 60" +
            "\n- 查询学生学分: SELECT s.sname, SUM(c.credit) as total_credits FROM s JOIN sc ON s.sno = sc.sno JOIN c ON sc.cno = c.cno WHERE sc.grade >= 60 GROUP BY s.sno, s.sname";
    }
}